import React, {useEffect, useState} from "react";
import {Col, Row, Tree, TreeDataNode} from "antd";
import { TreeProps } from 'antd/es/tree';
import {ScriptGroupTable, ServerItem, ServerScript} from "@/pages/script/components";
import {addTreeData} from "@/utils/tree";
import styled from "@emotion/styled";
import {ScriptTreeProp, ScriptTreeQueryProp} from "@/pages/script/modules";
import {scriptTree} from "@/api/script";

export interface DataNode extends TreeDataNode {
	id: number;
	parent_id?: number;
	item_type: number;
	children?: DataNode[];
}

interface TreeProp {
	id?: number;
	key?: React.Key;
	type_name?: number;
}

export type OperateType = "update" | "insert" | "delete";
type NodeType = "group" | "server"



const initTreeData: DataNode[] = [
	{ id: 0, title: '服务', key: '0', item_type: 0, children: [] }
];

/**
 * addTreeData 递归增加节点内容
 * @param list
 * @param item
 * @param pKey
 * @return DataNode[]
 */
function addTreeNode(list: ScriptTreeProp[], item: ScriptTreeProp[], pKey: number) : ScriptTreeProp[] {
	return list.map(node => {
		if (node.parentId === pKey) {
			if (node.children === undefined) {
				node.children = [];
			}
			node.children.push(...item);
			return node;
		}
		if (node.children) {
			addTreeData(node.children, pKey, item)
		}
		return node;
	});
}


/**
 * 更新节点
 * @param list
 * @param key
 * @param item
 * @param field 指定更新的属性
 */
export function updateTreeData(list: ScriptTreeProp[], key: number, item: ScriptTreeProp, ...field: ("title" )[]): ScriptTreeProp[] {
	return list.map((node) => {
		if (node.parentId === key) {
			if (node.children !== undefined) {
				let number = node.children.findIndex(inner => inner.key === item.key);
				if (number !== undefined && number !== -1) {
					if (field.length > 0) {
						node.children[number].title = item.title
					} else {
						node.children.splice(number, 1, item);
					}
				}
			}
			return node;
		}
		if (node.children) {
			updateTreeData(node.children, key, item)
		}
		return node;
	});
}


/**
 * deleteTreeNode 删除节点
 * @param list
 * @param parentKey
 * @param key
 */
function deleteTreeNode(list: ScriptTreeProp[], parentKey: React.Key, key: React.Key | React.Key[]): ScriptTreeProp[] {
	return list.map(node => {
		if (node.parentId === parentKey) {
			node.children = Array.isArray(key) ?
				node.children?.filter(item => !key.includes(item.key)) :
				node.children?.filter(item => item.key !== key)
			return node;
		}
		if (node.children) {
			deleteTreeNode(node.children, parentKey, key)
		}
		return node;
	})
}

const loadTree = (list: ScriptTreeProp[], key: React.Key, children: ScriptTreeProp[]): ScriptTreeProp[] =>
	list.map((node) => {
		if (node.key === key) {
			return {
				...node,
				children,
			};
		}
		if (node.children) {
			return {
				...node,
				children: loadTree(node.children, key, children),
			};
		}
		return node;
	});

export const ScriptPage = () => {

	const [treeQuery, setTreeQuery] = useState<ScriptTreeQueryProp>({id: 0, isTree: false, expendRoot: false})
	const [treeData, setTreeData] = useState<ScriptTreeProp[]>([{key: 0, title: '全部', isLeaf: false, itemType: 0, parentId: 0}]);
	const [selectNode, setSelectNode] = useState<ScriptTreeProp | undefined>(undefined);

	const onLoadData = (node: ScriptTreeProp) => new Promise<void>(async (resolve) => {
		const query: ScriptTreeQueryProp = {...treeQuery, id: node.key}
		const tree = await scriptTree(query);
		// const list = await permissionList(node.key)
		setTreeData(origin => loadTree(origin, node.key, tree));
		setTreeQuery(query);
		setSelectNode(node);
		// setDatasource(list);
		resolve();
		return;
	});

	const onSelect: TreeProps['onSelect'] = (selectedKeys: React.Key[], info) => {
		console.log('selected', selectedKeys);
		console.log('selected', info.node as unknown as ScriptTreeProp);
		setSelectNode(info.node as unknown as ScriptTreeProp);
	};

	const onCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
		console.log('onCheck', checkedKeys, info);
	};


	const insertTree = (data: ScriptTreeProp, pKey: number) => setTreeData(origin => addTreeNode(origin, [data], pKey))
	const deleteTree = (id: number | number[], pKey: React.Key) => setTreeData(origin => deleteTreeNode(origin, pKey, id))
	const updateTree = (data: ScriptTreeProp, pKey: number) => setTreeData(origin => updateTreeData(origin, pKey, data, "title"))

	// const loadData = async (data: ScriptTreeQueryProp) => {
	// 	const tree = await scriptTree(data)
	// 	setTreeData(tree);
	// }

	useEffect(() => {

	}, [])



	return <Container>
		<Row gutter={[16, 16]}>
			<Col flex="250px" className="tree-area">
				<Tree
					loadData={onLoadData}
					defaultExpandedKeys={[0]}
					onSelect={onSelect}
					onCheck={onCheck}
					treeData={treeData}
				/>
			</Col>
			<Col flex="auto">
				{ selectNode?.itemType === 0 ? <ScriptGroupTable
					updateNode={(data) => updateTree(data, 0)}
					deleteNode={(id) => deleteTree(id, 0)}
					insertNode={(data) => insertTree(data, 0)} /> : null }
				{ selectNode?.itemType === 1 ? <ServerItem
					sId={selectNode?.key}
					deleteNode={(id) => deleteTree(id, selectNode?.key)}
					insertNode={(data) => insertTree(data, selectNode?.key)}
					updateNode={(data) => updateTree(data, selectNode?.key)}/> : null }
				{ selectNode?.itemType === 2 ? <ServerScript serverId={selectNode?.key} /> : null }
			</Col>
		</Row>
	</Container>
}

const Container = styled.div`
	.tree-area {
		// border: 1px solid #f0f0f0;
		padding-top: 8px;
		padding-bottom: 8px;
		border-radius: 5px;
	}
`
